#include "datacollectionthread.h"

DataCollectionThread::DataCollectionThread(QObject *parent)
    :QThread(parent)
    ,firstRead(true)
    ,stopFlag(false)
    ,lastUser(0)
    ,lastSystem(0)
    ,lastIdle(0)
    ,lastTotal(0)
{
    currentData.idle = 0.0;
    currentData.system = 0.0;
    currentData.total = 0.0;
    currentData.user = 0.0;
    currentData.timestamp = QDateTime::currentMSecsSinceEpoch();
}

DataCollectionThread::~DataCollectionThread() {
    // 停止线程
    stopThread();
    //等待线程结束
    wait();
}

void DataCollectionThread::stopThread(){
    QMutexLocker locker(&dataMutex);
    stopFlag = true;
    // 唤醒所以线程
    waitCondition.wakeAll();
}

// 获取当前数据
CPUData DataCollectionThread::getCurrentData() const {
    QMutexLocker locker(&dataMutex);
    return currentData;
}

// 线程的执行逻辑
void DataCollectionThread::run() {
    qDebug() <<  "数据采集线程创建开始执行任务！";
    // 没有停止
    while(!stopFlag) {
        // 读取CPU 数据
        CPUData newdata = readCPUStats();

        {
            QMutexLocker locker(&dataMutex);
            currentData = newdata;
        }
        // 发送信号
        emit dataUpdated(newdata);

        // 因为要读取公共数据保证数据一致
        // 执行完之后等待1s
        QMutexLocker locker(&dataMutex);
        if(!stopFlag) {
            // 结束的时候直接weakall全部唤醒，或者等待1s自动唤醒
            waitCondition.wait(&dataMutex, 1000);
        }
    }
    qDebug() << "数据采集线程结束";
}

CPUData DataCollectionThread::readCPUStats() {
    CPUData data;

    // 打开 /proc/stat 读取数据
    QFile file("/proc/stat");
    if(!file.open(QIODeviceBase::ReadOnly | QIODeviceBase::Text)) {
        qDebug() << "打开文件失败";
        return data;
    }
    QTextStream in(&file);
    QString line = in.readLine();
    // 如果开头是cpu 说明读取正确
    if(line.startsWith("cpu ")) {
        // 分割字符串 设置删除空串
        QStringList parts =  line.split(" ", Qt::SkipEmptyParts);
        if(parts.size() >= 5) {
            // 转化为unsigned long long类型
            unsigned long long user = parts[1].toULongLong();
            unsigned long long nice = parts[2].toULongLong();
            unsigned long long system = parts[3].toULongLong();
            unsigned long long idle = parts[4].toULongLong();
            unsigned long long iowait = (parts.size() > 5) ? parts[5].toULongLong() : 0;
            unsigned long long irq = (parts.size() > 6) ? parts[6].toULongLong() : 0;
            unsigned long long softirq = (parts.size() > 7) ? parts[7].toULongLong() : 0;
            qDebug() << "当前CPU数据:" << user << nice << system;
            unsigned long long totalCurrent = user + nice + system + idle + iowait + irq + softirq;
            //第二次读取才开始计算使用率
            if (!firstRead) {
                // 计算时间差
                unsigned long long totalDiff = totalCurrent - lastTotal;
                unsigned long long idleDiff = idle + iowait - lastIdle;
                unsigned long long userDiff = user + nice - lastUser;
                unsigned long long systemDiff = system - lastSystem;

                if (totalDiff > 0) {
                    // 计算使用率百分比
                    data.total = ((double)(totalDiff - idleDiff) / totalDiff) * 100.0;
                    data.user = ((double)userDiff / totalDiff) * 100.0;
                    data.system = ((double)systemDiff / totalDiff) * 100.0;
                    data.idle = ((double)idleDiff / totalDiff) * 100.0;

                    // 确保数值在合理范围内
                    // 返回在合适范围的数值
                    data.total = qBound(0.0, data.total, 100.0);
                    data.user = qBound(0.0, data.user, 100.0);
                    data.system = qBound(0.0, data.system, 100.0);
                    data.idle = qBound(0.0, data.idle, 100.0);
                }
            }
            // 保存当前值用于下次计算
            lastTotal = totalCurrent;
            lastUser = user + nice;           // 用户时间 = user + nice
            lastSystem = system;               // 系统时间
            lastIdle = idle + iowait;          // 空闲时间 = idle + iowait
            firstRead = false;
        }
    }
    file.close();
    data.timestamp = QDateTime::currentMSecsSinceEpoch();
    return data;
}
